package com.pnkx.service.filter;

import com.alibaba.fastjson.JSON;
import com.pnkx.service.filter.domain.WrappedRequest;
import com.pnkx.service.filter.domain.WrappedResponse;
import com.pnkx.service.utils.SM2Utils;
import com.pnkx.service.utils.SM4Utils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

/**
 * @author by PHY
 * @classname encryptionFilter
 * @date 2021-12-15 16:27
 * @description: 描述
 */
@Component
public class EncryptionFilter extends OncePerRequestFilter{

    /** get请求关键字 */
    private static final String GET = "GET";
    /** 是否开启解密 */
    @Value("${encrypt.enabled}")
    private Boolean encryptEnabled;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        // 解密
        if (encryptEnabled && !GET.equals(request.getMethod())) {
            String requestKey = request.getHeader("RequestKey");
            String decrypt = SM2Utils.decrypt(requestKey);
            String sm4Key = decrypt.split("-")[1];
            String requestBody = getRequestBody(request);
            String requestBodyMw = null;
            Map<String, String> requestBodyMap = (Map<String, String>) JSON.parse(requestBody);
            // 解密请求报文
            if (!"".equals(requestBody)) {
                try {
                    requestBodyMw = SM4Utils.decryptEcb(sm4Key, requestBodyMap.get("cis_req_params"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            request = new WrappedRequest(request, requestBodyMw);
            // 加密返回值
            WrappedResponse wrapResponse = new WrappedResponse(response);
            chain.doFilter(request, wrapResponse);
            String content = wrapResponse.getContent();
            String responseBodyMw = null;
            try {
                // 加密
                responseBodyMw = SM4Utils.encryptEcb(sm4Key, content);
            } catch (Exception e) {
                e.printStackTrace();
            }
            response.setContentLength(-1);
            PrintWriter out = response.getWriter();
            out.write(responseBodyMw);
            out.flush();
            out.close();
        }
        chain.doFilter(request, response);
    }

    /**
     * 获取body体内容
     * @param req 请求
     * @return body体内容
     */
    private String getRequestBody(HttpServletRequest req) {
        try {
            BufferedReader reader = req.getReader();
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }
}
